#include "webTCP.h"

#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#include <string>
#include <iostream>
#include <exception>

TCP::TCP(std::string ip,int port_cmd,int port_data)
    :_port_cmd(port_cmd),_port_data(port_data)
{
    this->_IPv4 = ip;
    std::cout<<"开始建立通信"<<std::endl
            <<ip.data()<<std::endl
            <<"cmd port:"<<this->_port_cmd<<std::endl
           <<"data port:"<<this->_port_data<<std::endl;
    /* 创建套接字接口 */

    this->s_stream = socket(AF_INET, SOCK_STREAM, 0);  // 流数据
    this->s_cmd = socket(AF_INET, SOCK_STREAM, 0);    // 命令
    if(this->s_stream < 0 || this->s_cmd < 0)
    {
        std::cerr<< "套接字创建失败"<<std::endl;
        throw "套接字创建失败";
    }
    std::cout<<"套接字创建成功"<<std::endl;

    /* 套接字接口配置 */
    struct sockaddr_in sockAddrConfig;

    sockAddrConfig.sin_family = AF_INET;
    sockAddrConfig.sin_port = htons(port_data);
    sockAddrConfig.sin_addr.s_addr = inet_addr(ip.data());


    this->res_stream = connect(this->s_stream, (struct sockaddr*)&sockAddrConfig,sizeof(sockAddrConfig));
    if(this->res_stream <0)
    {
        std::cerr<<"流套接字连接失败"<<std::endl;
        // 抛出异常
        throw "流套接字连接失败";
    }

    sockAddrConfig.sin_port = htons(port_cmd);
    this->res_cmd = connect(this->s_cmd, (struct sockaddr*)&sockAddrConfig,sizeof(sockAddrConfig));
    if(this->res_cmd < 0)
    {
        std::cerr<<"命令套接字连接失败"<<std::endl;
        throw "命令套接字连接失败";
    }
    std::cout<<"套接字连接成功"<<std::endl
        <<"开始校验"<<std::endl;
    char buffer_cmd[4] = "Cli";
    this->res_cmd = send(this->s_cmd,buffer_cmd,4,0);
    std::cout<<"send cmd:"<<buffer_cmd<<std::endl;
    std::cout<<"通信建立成功"<<std::endl;
}

TCP::~TCP()
{
    close(s_stream);
    close(s_cmd);
}

bool TCP::sendCmd(const unsigned char * dataPtr,int dataLen)
{
    // 注意：默认命令是非常短的，所以不做拆包处理
    this->res_cmd = send(this->s_cmd,dataPtr,dataLen,0);
    if(this->res_cmd <0)
    {
        return false;
    }
    return true;
}

bool TCP::sendData(const unsigned char * dataPtr,int dataLen)
{
    for(int _i = dataLen/TCP_PACK_MAX_SIZE;
            _i>0;_i--)
    {
        this->res_stream = send(this->s_stream,dataPtr,TCP_PACK_MAX_SIZE,0);
        if(this->s_stream < 0)
        {
            return false;
        }
        dataPtr+=TCP_PACK_MAX_SIZE;
    }
    this->res_stream = send(this->s_stream,
                            dataPtr,
                            dataLen%TCP_PACK_MAX_SIZE,
                            0);
    if(this->res_stream <0)
        return  false;
    return true;
}
